<?php
namespace Ysian\Tools\sign;

use Ysian\Tools\file\File;

class Sign
{
    private $key; //私钥或者公钥
    private $signWay; //加密方式 private public
    private $signType='RSA'; //加密类型 RSA RSA2

    //实例化自己
    public static function create()
    {
        return new self();
    }

    //设置加密类型
    public function setSignType($signType = 'RSA')
    {
        $this->signType = $signType;
        return $this;
    }

    public function setKey($key)
    {
        $this->key = $key;
        $this->signWay = 'normal';
        return $this;
    }

    /**
     * @desc 设置私钥
     * @param $privateKey 私钥路径或者字符串
     * @return $this
     */
    public function setPrivateKey($privateKey)
    {
        try {
            $content = file_get_contents($privateKey);
        } catch (\Exception $exception) {
            $content = "-----BEGIN RSA PRIVATE KEY-----\n" .
                wordwrap($privateKey, 64, "\n", true) .
                "-----END RSA PRIVATE KEY-----\n";
        }
        $key = openssl_get_privatekey($content);
        $this->key = $key;
        $this->signWay = 'private';
        return $this;
    }

    /**
     * @desc 设置公钥钥
     * @param $privateKey 公钥路径或者字符串
     * @return $this
     */
    public function setPublicKey($publicKey)
    {
        try {
            $content = file_get_contents($publicKey);
        } catch (\Exception $exception) {
            $content = "-----BEGIN RSA PUBLIC KEY-----\n" .
                wordwrap($publicKey, 64, "\n", true) .
                "-----END RSA PUBLIC KEY-----\n";
        }
        $key = openssl_get_publickey($content);
        $this->key = $key;
        $this->signWay = 'public';
        return $this;
    }


    /**
     * @desc 使用私钥对数据进行加密
     * @param $params 加密数据
     * @return string
     * @throws \Exception
     */
    public function getSign(array $params)
    {
        if(!$this->key) {
            throw new \Exception('证书文件路径错误或者传入的证书格式错误');
        }
        //拼接要加密的数据
        $str = '';
        ksort($params);
        foreach ($params as $k => $v) {
            $str .= $k . '=' . $v . '&';
        }
        $str = rtrim($str, '&');

        //获取加密数据
        if($this->signWay=='private'){
            if ("RSA2" == $this->signType) {
                openssl_sign($str, $sign, $this->key, OPENSSL_ALGO_SHA256);
            } else {
                openssl_sign($str, $sign, $this->key);
            }
        } elseif($this->signWay=='public') {
            openssl_public_encrypt($str, $sign, $this->key);
        } else {

        }
        return base64_encode($sign);
    }

    /**
     * @desc 解密
     * @param $encrypted_data
     * @return mixed
     */
    public function decryptSign($encrypted_data)
    {
        if($this->signWay=='private'){
            openssl_private_decrypt(base64_decode($encrypted_data),$decrypted_data,$this->key);
        } elseif ($this->signWay=='public') {
            openssl_public_decrypt(base64_decode($encrypted_data),$decrypted_data,$this->key);
            $result = (openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256)===1);

        }
        parse_str($decrypted_data,$data);
        return $data;
    }

}